require 'digest/sha2'

# Representa uma chave usada no Chord ring.
# As chaves sao usadas tanto para identificar os no's quanto para identificar
# os elementos presentes no Chord.
# O hash usado para gerar a chave aqui e' o SHA2.
class Key
  attr_accessor :key
  
  MAX_VALUE = 'f' * Digest::SHA2.hexdigest('max_value').length

  # Construtor.
  # Calcula o hash para essa chave de acordo com o valor passado.
  def initialize(value)
    @key = Digest::SHA2.hexdigest(value).hex
  end

  # Determina se esta chave esta no intervalor passado.
  # Esse intervalo comeca em start_key e termina em end_key.
  # Os parametros include_start_key e include_end_key determinam se as chaves no
  # extremo dos intervalos devem ser incluidas ou nao.
  def is_in_range(start_key, end_key, include_start_key = true, include_end_key = true)
    unless include_start_key
      start_key += 1
    end
    
    unless include_end_key
      end_key -= 1
    end

    if start_key.key >= end_key.key
      return ((@key >= end_key.key and @key >= start_key.key) or
             (@key <= start_key.key and @key <= end_key.key))
    else
      return (@key >= start_key.key and @key <= end_key.key)
    end
  end
  
  def to_s
    @key.to_s
  end

  # Soma duas chaves.
  def +(number)
    number = number.key if number.is_a?(Key)

    key = Key.new('a')
    key.key = @key + number
    key.key -= MAX_VALUE.hex if key.key > MAX_VALUE.hex
    return key
  end

  # Subtrai duas chaves.
  def -(number)
    number = number.key if number.is_a?(Key)

    key = Key.new('a')
    key.key = @key - number
    key.key = MAX_VALUE.hex + key.key if key.key < 0
    return key
  end
  
  def eql?(other)
    key.to_s.eql?(other.key.to_s)
  end

  def set_key_by_string(str)
    @key = Integer(str)
  end
  
end
